package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.config.cronOne.CronTaskLoader;
import com.zhentao.config.cronTwo.CronTaskLoaderTwo;
import com.zhentao.domain.*;
import com.zhentao.domain.dto.*;
import com.zhentao.mapper.*;
import com.zhentao.result.Result;
import com.zhentao.service.SExaminationInformationService;
import com.zhentao.service.SRetakesInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.*;

/**
* @author 86150
* @description 针对表【s_examination_information】的数据库操作Service实现
* @createDate 2024-07-24 19:12:34
*/
@Service
@Lazy
public class SExaminationInformationServiceImpl extends ServiceImpl<SExaminationInformationMapper, SExaminationInformation>
    implements SExaminationInformationService{



    @Resource
    private SExaminationInformationMapper examinationInformationMapper;


    @Resource
    private STestPaperMapper sTestPaperMapper;

    @Resource
    private SQuestionMapper sQuestionMapper;

    @Resource
    private SSubjectMapper sSubjectMapper;

    @Resource
    private SClassMapper sClassMapper;

    @Resource
    private RedisTemplate<String,String> redisTemplate;


    @Resource
    private TUserRoleMapper userRoleMapper;


    //添加考试信息
    @Override
    public Result addExaminationInformation(SExaminationInformation examinationInformation) {
        TUserRole userRole = userRoleMapper.selectOne(Wrappers.<TUserRole>lambdaQuery().eq(TUserRole::getUId, examinationInformation.getUId()));
        if (userRole.getRId()==2){
            examinationInformation.setState(3);
        }
        QueryWrapper<SExaminationInformation> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("name",examinationInformation.getName());
        queryWrapper.eq("sub_id",examinationInformation.getSubId());
        List<SExaminationInformation> sExaminationInformations = this.examinationInformationMapper.selectList(queryWrapper);
        for (SExaminationInformation sExaminationInformation : sExaminationInformations){
            Date endTime = sExaminationInformation.getEndTime();
            if (endTime.after(new Date())){
                return Result.ERROR("该考试在此课程还未结束");
            }
        }
        examinationInformation.setRadioCount((examinationInformation.getRadioCounts().toString()+"_"+examinationInformation.getRadioScope().toString()));
        examinationInformation.setCheckCount((examinationInformation.getCheckCounts().toString()+"_"+examinationInformation.getCheckScope().toString()));
        examinationInformation.setJudgmentCount((examinationInformation.getJudgmentCounts().toString()+"_"+examinationInformation.getJudgmentScope().toString()));
        examinationInformation.setTextCount((examinationInformation.getTextCounts().toString()+"_"+examinationInformation.getTextScope().toString()));
        try {
            this.examinationInformationMapper.insert(examinationInformation);
            if (userRole.getRId()==1){
                redisTemplate.opsForList().leftPush("examinationInfo",examinationInformation.getId()+"_"+examinationInformation.getBeginTime()+"_"+examinationInformation.getEndTime()+"_"+0);
            }
            createTestPaper(examinationInformation.getId());
        } catch (Exception e) {
            return Result.ERROR("创建失败");
        }
        return Result.OK();
    }
    //生成试卷  参数为考试的id
    public void createTestPaper(Integer id) {
        //根据id查找这场考试
        SExaminationInformation sExaminationInformation = this.examinationInformationMapper.selectById(id);
        //单选题数量
        String radioCount = sExaminationInformation.getRadioCount();
        String[] s = radioCount.split("_");
        int radioCount1 = Integer.parseInt(s[0]);
        //多选题数量
        String checkCount = sExaminationInformation.getCheckCount();
        String[] s1 = checkCount.split("_");
        int checkCount1 = Integer.parseInt(s1[0]);
        //判断题数量
        String judgmentCount = sExaminationInformation.getJudgmentCount();
        String[] s2 = judgmentCount.split("_");
        int judgmentCount1 = Integer.parseInt(s2[0]);
        //填空题数量
        String textCount = sExaminationInformation.getTextCount();
        String[] s3 = textCount.split("_");
        int textCount1 = Integer.parseInt(s3[0]);
        //获取这场考试阶段对应的题目
        QueryWrapper<SQuestion> queryWrapper = new QueryWrapper<SQuestion>();
        queryWrapper.eq("sub_id", sExaminationInformation.getSubId());
        queryWrapper.eq("state",0);
        List<SQuestion> list = this.sQuestionMapper.selectList(queryWrapper);
        //所有单选题列表
        List<SQuestion> radioList = new ArrayList<>();
        //所有多选题列表
        List<SQuestion> checkList = new ArrayList<>();
        //所有判断题列表
        List<SQuestion> judgmentList = new ArrayList<>();
        //所有简答题列表
        List<SQuestion> textList = new ArrayList<>();
        for (SQuestion sQuestion : list) {
            if (sQuestion.getTypeId() == 1) {
                radioList.add(sQuestion);
            } else if (sQuestion.getTypeId() == 2) {
                checkList.add(sQuestion);
            } else if (sQuestion.getTypeId() == 3) {
                judgmentList.add(sQuestion);
            } else if (sQuestion.getTypeId() == 4) {
                textList.add(sQuestion);
            }
        }
        //要添加的单选题
        Set<SQuestion> radioset = new HashSet<>();
        //要添加的多选题
        Set<SQuestion> checkset = new HashSet<>();
        //要添加的判断题
        Set<SQuestion> judgmentset = new HashSet<>();
        //要添加的简答题
        Set<SQuestion> textset = new HashSet<>();
        //添加到单选set中
        if (radioList.isEmpty()){

        }else {
            for (int i = 0; i < radioCount1; i++) {
                Random random = new Random();
                int index = random.nextInt(radioList.size());
                SQuestion sQuestion = radioList.get(index);
                radioset.add(sQuestion);
            }
        }
        //添加到多选set中
        if (checkList.isEmpty()){

        }else {
            for (int i = 0; i < checkCount1; i++) {
                Random random = new Random();
                int index = random.nextInt(checkList.size());
                SQuestion sQuestion = checkList.get(index);
                checkset.add(sQuestion);
            }
        }
        //添加到判断题set中
        if (judgmentList.isEmpty()){

        }else {
            for (int i = 0; i < judgmentCount1; i++) {
                Random random = new Random();
                int index = random.nextInt(judgmentList.size());
                SQuestion sQuestion = judgmentList.get(index);
                judgmentset.add(sQuestion);
            }
        }
        //添加到简答题set中
        if (textList.isEmpty()){

        }else {
            for (int i = 0; i < textCount1; i++) {
                Random random = new Random();
                int index = random.nextInt(textList.size());
                SQuestion sQuestion = textList.get(index);
                textset.add(sQuestion);
            }
        }
        //添加单选题到试卷
        for (SQuestion sQuestion : radioset) {
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(sQuestion.getId());
            sTestPaper.setTestinfoId(id);
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加多选题到试卷
        for (SQuestion sQuestion : checkset) {
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(sQuestion.getId());
            sTestPaper.setTestinfoId(id);
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加判断题到试卷
        for (SQuestion sQuestion : judgmentset) {
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(sQuestion.getId());
            sTestPaper.setTestinfoId(id);
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加简答题到试卷
        for (SQuestion sQuestion : textset) {
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(sQuestion.getId());
            sTestPaper.setTestinfoId(id);
            this.sTestPaperMapper.insert(sTestPaper);
        }
    }

    //查找考试信息
    @Override
    public Result getExaminationInfoList(SExaminationInformationDto dto) {
        Page<SExaminationInformation> page=new Page<>(dto.getPageNum(),dto.getPageSize());
        Page<SExaminationInformation> list = examinationInformationMapper.getExaminationInfoList(page, dto);
        return Result.OK(list);
    }

    //根据考试信息id查找考试信息
    @Override
    public Result getExaminationInfoById(Integer id) {
        SExaminationInformation sExaminationInformation = this.examinationInformationMapper.getExaminationInfoById(id);
        return Result.OK(sExaminationInformation);
    }

    //获取导出的信息
    @Override
    public List<SExaminationInformationExport> getSExaminationInformationExport() {
        List<SExaminationInformation> list = examinationInformationMapper.getSExaminationInformationExport();
        List<SExaminationInformationExport> list1=new ArrayList<>();
        for (SExaminationInformation sExaminationInformation : list){
            SExaminationInformationExport sExaminationInformationExport = new SExaminationInformationExport();
            sExaminationInformationExport.setId(sExaminationInformation.getId());
            sExaminationInformationExport.setName(sExaminationInformation.getName());
            sExaminationInformationExport.setBeginTime(sExaminationInformation.getBeginTime());
            sExaminationInformationExport.setEndTime(sExaminationInformation.getEndTime());
            sExaminationInformationExport.setExamDuration(sExaminationInformation.getExamDuration());
            sExaminationInformationExport.setState(sExaminationInformation.getState());
            SSubject sSubject = this.sSubjectMapper.selectById(sExaminationInformation.getSubId());
            sExaminationInformationExport.setSubjectName(sSubject.getSubjectName());
            sExaminationInformationExport.setRadioCount(sExaminationInformation.getRadioCount());
            sExaminationInformationExport.setCheckCount(sExaminationInformation.getCheckCount());
            sExaminationInformationExport.setJudgmentCount(sExaminationInformation.getJudgmentCount());
            sExaminationInformationExport.setTextCount(sExaminationInformation.getTextCount());
            list1.add(sExaminationInformationExport);
        }
        return list1;
    }

    //获取试卷
    @Override
    public Result getTestPaper(Integer id) {
        if (this.examinationInformationMapper.selectById(id)!=null){
            List<STestPaper> sTestPaper = this.sTestPaperMapper.selectList(new QueryWrapper<STestPaper>().eq("testinfo_id",id));
            List<SQuestion> sQuestion = new ArrayList<>();
            for (STestPaper sTestPaper1 : sTestPaper){
                SQuestion sQuestion1 = this.sQuestionMapper.selectById(sTestPaper1.getQuestionId());
                sQuestion.add(sQuestion1);
            }
            for (SQuestion question:sQuestion){
                if (question.getTypeId()==1 || question.getTypeId()==2){
                    String question1 = question.getQuestion();
                    String[] split = question1.split("/");
                    String answer = split[1];
                    String[] s = answer.split("_");
                    question.setAnswer(s);
                }
            }
            return Result.OK(sQuestion);
        }
        return Result.ERROR();
    }

    //添加考试信息（自己选题）
    @Override
    public Result addExaminationInformationBySelf(AdSExaminationInformation adSExaminationInformation) {
        SExaminationInformation sExaminationInformation = new SExaminationInformation();
        TUserRole userRole = userRoleMapper.selectOne(Wrappers.<TUserRole>lambdaQuery().eq(TUserRole::getUId, adSExaminationInformation.getUId()));
        if (userRole.getRId()==2){
            sExaminationInformation.setState(3);
        }
        adSExaminationInformation.setRadioCount(adSExaminationInformation.getRadioCounts().length+"_"+adSExaminationInformation.getRadioScope().toString());
        adSExaminationInformation.setCheckCount(adSExaminationInformation.getCheckCounts().length+"_"+adSExaminationInformation.getCheckScope().toString());
        adSExaminationInformation.setJudgmentCount(adSExaminationInformation.getJudgmentCounts().length+"_"+adSExaminationInformation.getJudgmentScope().toString());
        adSExaminationInformation.setTextCount(adSExaminationInformation.getTextCounts().length+"_"+adSExaminationInformation.getTextScope().toString());

        BeanUtils.copyProperties(adSExaminationInformation,sExaminationInformation);

        QueryWrapper<SExaminationInformation> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("name",sExaminationInformation.getName());
        queryWrapper.eq("sub_id",sExaminationInformation.getSubId());
        List<SExaminationInformation> sExaminationInformations = this.examinationInformationMapper.selectList(queryWrapper);
        System.err.println(sExaminationInformation);
        for (SExaminationInformation sExaminationInformation1 : sExaminationInformations){
            Date endTime = sExaminationInformation1.getEndTime();
            if (endTime.after(new Date())){
                return Result.ERROR("该考试在此课程还未结束");
            }
        }
        this.examinationInformationMapper.insert(sExaminationInformation);
        redisTemplate.opsForList().leftPush("examinationInfo",sExaminationInformation.getId()+"_"+sExaminationInformation.getBeginTime()+"_"+sExaminationInformation.getEndTime()+"_"+0);
        //添加单选题到试卷
        for (int i = 0; i < adSExaminationInformation.getRadioCounts().length; i++){
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(adSExaminationInformation.getRadioCounts()[i]);
            sTestPaper.setTestinfoId(sExaminationInformation.getId());
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加多选题到试卷
        for (int i = 0; i < adSExaminationInformation.getCheckCounts().length; i++){
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(adSExaminationInformation.getCheckCounts()[i]);
            sTestPaper.setTestinfoId(sExaminationInformation.getId());
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加判断题到试卷
        for (int i = 0; i < adSExaminationInformation.getJudgmentCounts().length; i++){
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(adSExaminationInformation.getJudgmentCounts()[i]);
            sTestPaper.setTestinfoId(sExaminationInformation.getId());
            this.sTestPaperMapper.insert(sTestPaper);
        }
        //添加简答题到试卷
        for (int i = 0; i < adSExaminationInformation.getTextCounts().length; i++){
            STestPaper sTestPaper = new STestPaper();
            sTestPaper.setQuestionId(adSExaminationInformation.getTextCounts()[i]);
            sTestPaper.setTestinfoId(sExaminationInformation.getId());
            this.sTestPaperMapper.insert(sTestPaper);
        }
        return Result.OK();
    }



    //修改考试信息
    @Override
    public Result updateExaminationInformation(SExaminationInformation sExaminationInformation) {
        SExaminationInformation sExaminationInformation1 = this.examinationInformationMapper.selectById(sExaminationInformation.getId());
        if (sExaminationInformation1.getState()!=0){
            return Result.ERROR("考试已开始，不能修改");
        }
        ListOperations<String, String> stringObjectListOperations = redisTemplate.opsForList();
        stringObjectListOperations.remove("examinationInfo",0,sExaminationInformation1.getId()+"_"+sExaminationInformation1.getBeginTime()+"_"+sExaminationInformation1.getEndTime()+"_"+sExaminationInformation1.getState());
        sExaminationInformation.setRadioCount((sExaminationInformation.getRadioCounts().toString()+"_"+sExaminationInformation.getRadioScope().toString()));
        sExaminationInformation.setCheckCount((sExaminationInformation.getCheckCounts().toString()+"_"+sExaminationInformation.getCheckScope().toString()));
        sExaminationInformation.setJudgmentCount((sExaminationInformation.getJudgmentCounts().toString()+"_"+sExaminationInformation.getJudgmentScope().toString()));
        sExaminationInformation.setTextCount((sExaminationInformation.getTextCounts().toString()+"_"+sExaminationInformation.getTextScope().toString()));
        BeanUtils.copyProperties(sExaminationInformation,sExaminationInformation1);
        int i = this.examinationInformationMapper.updateById(sExaminationInformation1);
        redisTemplate.opsForList().leftPush("examinationInfo",sExaminationInformation1.getId()+"_"+sExaminationInformation1.getBeginTime()+"_"+sExaminationInformation1.getEndTime()+"_"+0);
       this.sTestPaperMapper.delete(new QueryWrapper<STestPaper>().eq("testinfo_id",sExaminationInformation.getId()));
       this.createTestPaper(sExaminationInformation.getId());
       return Result.OK(i);
    }

    //修改考试状态
    @Scheduled(cron = "0/30  * * * * ?")
    public void publishExamination(){
        System.err.println("修改考试状态定时任务执行");
        ListOperations<String, String> stringStringListOperations = redisTemplate.opsForList();
        List<String> examinationInfo = stringStringListOperations.range("examinationInfo", 0, -1);
        if (examinationInfo!=null) {
            examinationInfo.forEach(s -> {

                String[] s1 = s.split("_");
                DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss 'CST' yyyy",Locale.US);
                Date beginTime = null;
                Date endTime = null;
                try {
                    beginTime = df.parse(s1[1]);
                    endTime = df.parse(s1[2]);
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                //把CST格式转换成普通日期格式
                DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                sdf.format(beginTime);
                sdf.format(endTime);
                if (s1[3].equals("0")) {
                    if (new Date().after(beginTime)) {
                        SExaminationInformation sExaminationInformation = this.examinationInformationMapper.selectById(s1[0]);
                        if (sExaminationInformation!=null){
                            ListOperations<String, String> stringObjectListOperations = redisTemplate.opsForList();
                            stringObjectListOperations.remove("examinationInfo", 0, sExaminationInformation.getId() + "_" + sExaminationInformation.getBeginTime() + "_" + sExaminationInformation.getEndTime() + "_" + sExaminationInformation.getState());
                            sExaminationInformation.setState(1);
                            this.examinationInformationMapper.updateById(sExaminationInformation);
                            redisTemplate.opsForList().leftPush("examinationInfo", sExaminationInformation.getId() + "_" + sExaminationInformation.getBeginTime() + "_" + sExaminationInformation.getEndTime() + "_" + 1);
                        }
                    }
                } else if (s1[3].equals("1")) {
                    if (new Date().after(endTime)) {
                        SExaminationInformation sExaminationInformation = this.examinationInformationMapper.selectById(s1[0]);
                        if (sExaminationInformation!=null){
                            ListOperations<String, String> stringObjectListOperations = redisTemplate.opsForList();
                            stringObjectListOperations.remove("examinationInfo", 0, sExaminationInformation.getId() + "_" + sExaminationInformation.getBeginTime() + "_" + sExaminationInformation.getEndTime() + "_" + sExaminationInformation.getState());
                            sExaminationInformation.setState(2);
                            this.examinationInformationMapper.updateById(sExaminationInformation);
                        }

                    }
                }
            });
        }
    }


    @Resource
    private CronTaskLoader cronTaskLoader;

    @Resource
    private CronTaskLoaderTwo cronTaskLoaderTwo;

    private String month="12";
    private String day="1-29";
    private String month1="12";
    private String day1="1-29";
    private Integer[] classIds;
    private DailyTime[] beginEndTime;
    //发布教学周期日考
    @Override
    public Result addDailyExams(CycleDailyExams cycleDailyExams) {
        //教学周期的开始结束时间
        String[] cycleTime = cycleDailyExams.getCycleTime();
        LocalDate CycleBeginTime= LocalDate.parse(cycleTime[0]);
        LocalDate CycleEndTime= LocalDate.parse(cycleTime[1]);
        if (CycleBeginTime.getMonth()==CycleEndTime.getMonth()){
            month= String.valueOf(CycleBeginTime.getMonthValue());
            day=CycleBeginTime.getDayOfMonth()+"-"+CycleEndTime.getDayOfMonth();
            //刷新定时任务的时间
            int x= Integer.parseInt(month);
            if (x==12){
                x=11;
            }else {
                x=x-2;
            }
            month1= String.valueOf(x);
            cronTaskLoader.cronTaskConfigRefresh();
            cronTaskLoaderTwo.cronTaskConfigRefresh();
        }else {
            month= String.valueOf(CycleBeginTime.getMonthValue());
            month1= String.valueOf(CycleEndTime.getMonthValue());
            //获取这个月份的天数
            YearMonth yearMonth = YearMonth.from(CycleBeginTime);
            int daysInMonth = yearMonth.lengthOfMonth();
            day=CycleBeginTime.getDayOfMonth()+"-"+daysInMonth;;
            day1=1+"-"+CycleEndTime.getDayOfMonth();
            //刷新定时任务的时间
            cronTaskLoader.cronTaskConfigRefresh();
            cronTaskLoaderTwo.cronTaskConfigRefresh();
        }
        //班级的id集合
        classIds = cycleDailyExams.getClassId();
        //每个班级的开始结束时间
        beginEndTime = cycleDailyExams.getBeginEndTime();
        return Result.OK();
    }


    //根据讲师id查找该讲师带班的对应考试
    @Override
    public Result getExaminationInfoListByTeacherId(Integer tid,SExaminationInformationDto dto) {
        Page<SExaminationInformation> page=new Page<>();
        //找到这个讲师所带的班级
        QueryWrapper<SClass> queryWrapper=new QueryWrapper<SClass>();
        queryWrapper.lambda().eq(SClass::getTeacherId,tid);
        List<SClass> sClasses = this.sClassMapper.selectList(queryWrapper);
        List<Integer> list=new ArrayList();
        //找到这个班级对应的考试
        if (sClasses.size()!=0){
            for (SClass sClass : sClasses){
                list.add(sClass.getClassId());
            }
            Page<SExaminationInformation> sExaminationInformations = examinationInformationMapper.getExaminationInfoListByTeacherId(page,list,dto);
            return Result.OK(sExaminationInformations);
        }
        return Result.ERROR("暂时没有考试信息");
    }

    @Override
    public Integer getTestNum() {
        Integer testNum=examinationInformationMapper.getTestNum();
        return testNum;
    }


    public CycleDailyExams returnCycleDailyExams(){
        CycleDailyExams cycleDailyExams = new CycleDailyExams();
        cycleDailyExams.setClassId(classIds);
        cycleDailyExams.setBeginEndTime(beginEndTime);
        return cycleDailyExams;
    }
    public String returnCron(){
        return "0 0 16"+" "+day+" "+month+" ?";
    }

    public String returnCronTwo(){
        return "0 0 16"+" "+day1+" "+month1+" ?";
    }




}




